import { Injectable } from "@nestjs/common";
import { InjectDataSource } from "@nestjs/typeorm";
import { DataSource } from "typeorm";

@Injectable()
export class DatabaseInitService {
  constructor(
    @InjectDataSource()
    private dataSource: DataSource
  ) {}

  /**
   * 初始化数据库表结构
   */
  async initializeDatabase() {
    try {
      console.log("🔧 开始初始化数据库表结构...");

      // 首先设置MySQL会话配置
      await this.setupMySQLSession();

      // 创建shop_goods表
      await this.createShopGoodsTable();

      // 创建character_skills表（如果不存在）
      await this.createCharacterSkillsTable();

      // 插入初始数据
      await this.insertInitialData();

      console.log("✅ 数据库表结构初始化完成");
    } catch (error) {
      console.error("❌ 数据库初始化失败:", error);
      throw error;
    }
  }

  /**
   * 设置MySQL会话配置
   */
  private async setupMySQLSession() {
    try {
      console.log("🔧 设置MySQL会话配置...");

      // 设置会话级别的sql_mode为兼容模式
      await this.dataSource.query("SET SESSION sql_mode = ''");
      console.log("✅ 已设置会话sql_mode为空（兼容模式）");

      // 设置时区
      await this.dataSource.query("SET SESSION time_zone = '+08:00'");
      console.log("✅ 已设置时区为+08:00");

      // 禁用外键检查
      await this.dataSource.query("SET SESSION FOREIGN_KEY_CHECKS=0");
      console.log("✅ 已禁用外键检查");

      // 设置字符集
      await this.dataSource.query(
        "SET SESSION character_set_connection = 'utf8mb4'"
      );
      await this.dataSource.query(
        "SET SESSION character_set_client = 'utf8mb4'"
      );
      await this.dataSource.query(
        "SET SESSION character_set_results = 'utf8mb4'"
      );
      console.log("✅ 已设置字符集为utf8mb4");

      console.log("✅ MySQL会话配置设置完成");
    } catch (error) {
      console.error("❌ 设置MySQL会话配置失败:", error);
      throw error;
    }
  }

  /**
   * 创建商店商品表
   */
  private async createShopGoodsTable() {
    const tableExists = await this.checkTableExists("shop_goods");
    if (tableExists) {
      console.log("📋 shop_goods表已存在，跳过创建");
      return;
    }

    console.log("📋 创建shop_goods表...");

    const createTableSQL = `
      CREATE TABLE IF NOT EXISTS \`shop_goods\` (
        \`id\` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
        \`goodsId\` int(11) NOT NULL COMMENT '商品ID',
        \`name\` varchar(100) NOT NULL COMMENT '商品名称',
        \`description\` text COMMENT '商品描述',
        \`picture\` varchar(128) COMMENT '商品图片',
        \`goodsType\` int(11) NOT NULL COMMENT '商品类型：1-药品，2-装备，3-材料，4-消耗品，5-特殊物品',
        \`currencyType\` int(11) NOT NULL COMMENT '货币类型：1-金币，2-银币，3-积分',
        \`price\` int(11) NOT NULL COMMENT '商品价格',
        \`levelRequirement\` int(11) NOT NULL DEFAULT 0 COMMENT '商品等级要求',
        \`status\` int(11) NOT NULL DEFAULT 1 COMMENT '商品状态：0-下架，1-上架',
        \`dailyLimit\` int(11) NOT NULL DEFAULT 0 COMMENT '每日购买限制',
        \`stock\` int(11) NOT NULL DEFAULT -1 COMMENT '商品库存',
        \`created_at\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
        \`updated_at\` timestamp NULL DEFAULT NULL COMMENT '更新时间',
        PRIMARY KEY (\`id\`),
        UNIQUE KEY \`uk_goodsId\` (\`goodsId\`),
        KEY \`idx_currencyType\` (\`currencyType\`),
        KEY \`idx_goodsType\` (\`goodsType\`),
        KEY \`idx_status\` (\`status\`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商店商品表'
    `;

    await this.dataSource.query(createTableSQL);
    console.log("✅ shop_goods表创建成功");
  }

  /**
   * 创建角色技能表
   */
  private async createCharacterSkillsTable() {
    console.log("📋 强制重新创建character_skills表...");

    // 强制删除现有表
    try {
      await this.dataSource.query("DROP TABLE IF EXISTS `character_skills`");
      console.log("🗑️ 已删除旧的character_skills表");
    } catch (error) {
      console.log("⚠️ 删除旧表时出现警告:", error);
    }

    console.log("📋 创建character_skills表...");

    const createTableSQL = `
      CREATE TABLE IF NOT EXISTS \`character_skills\` (
        \`id\` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
        \`characterId\` int(11) NOT NULL COMMENT '角色ID',
        \`skillId\` int(11) NOT NULL COMMENT '技能ID',
        \`grade\` int(11) NOT NULL DEFAULT 0 COMMENT '技能等级',
        \`hua\` int(11) NOT NULL DEFAULT 0 COMMENT '技能花数',
        \`useCount\` int(11) NOT NULL DEFAULT 0 COMMENT '使用次数',
        \`skillType\` int(11) NOT NULL COMMENT '技能类型',
        \`skillName\` varchar(50) NOT NULL COMMENT '技能名称',
        \`skillSide\` int(11) NOT NULL COMMENT '技能方向',
        \`skillShort\` varchar(10) NOT NULL COMMENT '技能简称',
        \`skillAni\` varchar(50) NOT NULL COMMENT '技能动画',
        \`status\` int(11) NOT NULL DEFAULT 1 COMMENT '技能状态',
        \`obtainedAt\` datetime NOT NULL COMMENT '获得时间',
        \`created_at\` datetime NOT NULL COMMENT '创建时间',
        \`updated_at\` datetime NOT NULL COMMENT '更新时间',
        PRIMARY KEY (\`id\`),
        UNIQUE KEY \`uk_character_skill\` (\`characterId\`, \`skillId\`),
        KEY \`idx_characterId\` (\`characterId\`),
        KEY \`idx_skillId\` (\`skillId\`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色技能表'
    `;

    await this.dataSource.query(createTableSQL);
    console.log("✅ character_skills表创建成功");
  }

  /**
   * 插入初始数据
   */
  private async insertInitialData() {
    // 插入商店商品数据
    await this.insertShopGoodsData();

    // 插入角色技能数据
    await this.insertCharacterSkillsData();

    // 插入技能升级阈值（若不存在）
    await this.insertSkillUpgradeThresholds();
  }

  private async insertSkillUpgradeThresholds() {
    // 建表（若未建）
    const exists = await this.checkTableExists("skill_upgrade_thresholds");
    if (!exists) {
      const sql = `
        CREATE TABLE IF NOT EXISTS skill_upgrade_thresholds (
          id int(11) NOT NULL AUTO_INCREMENT,
          skillName varchar(100) NOT NULL,
          nextGrade int(11) NOT NULL,
          requiredProficiency int(11) NOT NULL,
          created_at datetime NOT NULL,
          updated_at datetime NULL,
          UNIQUE KEY uk_skill_grade (skillName, nextGrade),
          PRIMARY KEY (id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='技能升级阈值表';
      `;
      await this.dataSource.query(sql);
    }

    // 已迁出为独立脚本导入，后端不再进行任何CSV或表数据导入行为
  }

  /**
   * 插入商店商品数据
   */
  private async insertShopGoodsData() {
    const goodsData = [
      // 金币商品
      [
        68,
        "高级装备强化石",
        "用于强化高级装备，提升装备属性",
        "equip_stone.png",
        2,
        1,
        100,
        10,
        1,
        5,
        -1,
      ],
      [
        69,
        "稀有材料包",
        "包含各种稀有材料，用于制作高级装备",
        "rare_material.png",
        3,
        1,
        200,
        15,
        1,
        3,
        -1,
      ],
      [
        70,
        "经验加成卡",
        "使用后获得经验加成效果",
        "exp_boost.png",
        4,
        1,
        50,
        5,
        1,
        10,
        -1,
      ],
      [
        78,
        "护身符",
        "随身物品,玩家死亡时可避免经验值损失,每死亡一次,消耗一个护身符",
        "hsf.png",
        5,
        1,
        298,
        1,
        1,
        99,
        -1,
      ],

      // 银币商品（医馆药品）
      [1, "跌打药", "恢复生命值+500", "medicine_1.png", 1, 2, 50, 1, 1, 0, -1],
      [2, "止血药", "恢复生命值+1000", "medicine_2.png", 1, 2, 60, 1, 1, 0, -1],
      [3, "金疮药", "恢复生命值+1500", "medicine_3.png", 1, 2, 70, 1, 1, 0, -1],
      [4, "麻沸散", "恢复生命值+2000", "medicine_4.png", 1, 2, 80, 1, 1, 0, -1],
      [
        5,
        "酥和散",
        "恢复生命值+3000",
        "medicine_5.png",
        1,
        2,
        200,
        5,
        1,
        0,
        -1,
      ],
      [
        6,
        "断续膏",
        "恢复生命值+4500",
        "medicine_6.png",
        1,
        2,
        300,
        8,
        1,
        0,
        -1,
      ],
      [
        7,
        "三黄丸",
        "恢复生命值+6000",
        "medicine_7.png",
        1,
        2,
        400,
        10,
        1,
        0,
        -1,
      ],
      [
        9,
        "熊胆丸",
        "恢复生命值+10000",
        "medicine_9.png",
        1,
        2,
        600,
        15,
        1,
        0,
        -1,
      ],
      [
        10,
        "首乌丸",
        "恢复生命值+15000",
        "medicine_10.png",
        1,
        2,
        800,
        20,
        1,
        0,
        -1,
      ],
      [
        11,
        "雪参丸",
        "恢复生命值+20000",
        "medicine_11.png",
        1,
        2,
        1000,
        25,
        1,
        0,
        -1,
      ],
      [
        12,
        "小还丹",
        "恢复生命值+25%",
        "medicine_12.png",
        1,
        2,
        200,
        12,
        1,
        0,
        -1,
      ],
    ];

    for (const goods of goodsData) {
      const [
        goodsId,
        name,
        description,
        picture,
        goodsType,
        currencyType,
        price,
        levelRequirement,
        status,
        dailyLimit,
        stock,
      ] = goods;

      const insertSQL = `
        INSERT IGNORE INTO \`shop_goods\` 
        (\`goodsId\`, \`name\`, \`description\`, \`picture\`, \`goodsType\`, \`currencyType\`, \`price\`, \`levelRequirement\`, \`status\`, \`dailyLimit\`, \`stock\`)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      `;

      await this.dataSource.query(insertSQL, [
        goodsId,
        name,
        description,
        picture,
        goodsType,
        currencyType,
        price,
        levelRequirement,
        status,
        dailyLimit,
        stock,
      ]);
    }

    console.log("✅ 商店商品数据插入完成");
  }

  /**
   * 插入角色技能数据
   */
  private async insertCharacterSkillsData() {
    // 检查characters表是否存在
    const tableExists = await this.checkTableExists("characters");
    if (!tableExists) {
      console.log("⚠️ characters表不存在，跳过角色技能数据插入");
      return;
    }

    // 为角色ID 1 和 2304 创建默认技能
    const characters = [1, 2304];

    for (const characterId of characters) {
      // 获取角色信息
      const character = await this.dataSource.query(
        "SELECT roleType FROM characters WHERE id = ?",
        [characterId]
      );

      if (character.length === 0) continue;

      const roleType = character[0].roleType;
      const skills = this.getDefaultSkillsByRoleType(roleType);

      for (const skill of skills) {
        const insertSQL = `
          INSERT IGNORE INTO \`character_skills\` 
          (\`characterId\`, \`skillId\`, \`grade\`, \`hua\`, \`useCount\`, \`skillType\`, \`skillName\`, \`skillSide\`, \`skillShort\`, \`skillAni\`, \`status\`, \`obtainedAt\`, \`created_at\`, \`updated_at\`)
          VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), NULL)
        `;

        await this.dataSource.query(insertSQL, [
          characterId,
          skill.id,
          0, // grade: 默认等级0
          0, // hua: 默认花数0
          0, // useCount: 默认使用次数0
          skill.type,
          skill.name,
          skill.side,
          skill.short,
          skill.ani,
          1, // status: 默认已激活
        ]);
      }
    }

    console.log("✅ 角色技能数据插入完成");
  }

  /**
   * 根据角色类型获取默认技能
   */
  private getDefaultSkillsByRoleType(roleType: number) {
    switch (roleType) {
      case 1: // 武士
        return [
          {
            id: 1,
            type: 1,
            name: "舍身取义",
            side: 1,
            short: "舍",
            ani: "she-8",
          },
          {
            id: 9,
            type: 1,
            name: "劈头盖脸",
            side: 1,
            short: "劈",
            ani: "pi-6",
          },
          {
            id: 15,
            type: 1,
            name: "坚如磐石",
            side: 2,
            short: "固",
            ani: "gu-4",
          },
        ];
      case 2: // 文人
        return [
          {
            id: 5,
            type: 2,
            name: "围点打援",
            side: 1,
            short: "围",
            ani: "wei-6",
          },
          {
            id: 11,
            type: 2,
            name: "乱作一团",
            side: 1,
            short: "乱",
            ani: "luan-4",
          },
          {
            id: 18,
            type: 2,
            name: "隐姓埋名",
            side: 2,
            short: "暗",
            ani: "an-4",
          },
        ];
      case 3: // 异师
        return [
          {
            id: 8,
            type: 3,
            name: "煽风点火",
            side: 1,
            short: "火",
            ani: "huo-4",
          },
          {
            id: 13,
            type: 3,
            name: "天打雷劈",
            side: 1,
            short: "雷",
            ani: "lei-4",
          },
          {
            id: 16,
            type: 3,
            name: "神出鬼没",
            side: 2,
            short: "神",
            ani: "shen-4",
          },
        ];
      default:
        return [];
    }
  }

  /**
   * 检查表是否存在
   */
  private async checkTableExists(tableName: string): Promise<boolean> {
    try {
      const result = await this.dataSource.query(
        "SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = ?",
        ["nextjs", tableName]
      );
      return result[0].count > 0;
    } catch (error) {
      return false;
    }
  }
}
